package com.siecom.transport.serialport;

import android.os.Build;
import android.util.Log;


import com.siecom.nativelibs.SerialPort;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;



/**
 * @author benjaminwan
 *���ڸ������
 */
public class SerialHelper {
	private SerialPort mSerialPort;
	private OutputStream mOutputStream;
	private InputStream mInputStream;
	private ReadThread mReadThread;
	private SendThread mSendThread;
	//private String sPort="/dev/ttySAC1";
	private String sPort="/dev/ttyHSL0";
	private int iBaudRate=115200;
	private boolean _isOpen=false;
	private byte[] _bLoopData=new byte[]{0x30};
	private int iDelay=500;

	private byte[] FifoBuffer=new byte[512];
	private int ofst_free=0,ofst_last=0;


	//----------------------------------------------------
	public SerialHelper(String sPort, int iBaudRate){
		this.sPort = sPort;
		this.iBaudRate=iBaudRate;
	}
	public SerialHelper(){
		File file;
		//this("/dev/ttySAC1",115200);
		//this("/dev/ttyHSL1",115200);
		Log.d("build",Build.MODEL);
		if(Build.MODEL.equals("msm8937 for arm64")||Build.MODEL.equals("W-500A")) {
			file = new File("/dev/ttyHSL1");//NFC ttyHSL2
			if(file.exists()==true) {
				this.sPort = "/dev/ttyHSL1";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("US804")) {
			file = new File("/dev/ttyHSL2");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyHSL2";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("US811")){
			file = new File("/dev/ttyHSL0");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyHSL0";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("V100")) {
			file = new File("/dev/ttyHSL2");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyHSL2";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("ESAPOS E6")){
			file = new File("/dev/ttyMT1");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyMT1";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("US817")||Build.MODEL.equals("PAD")){
			file = new File("/dev/ttyHSL0");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyHSL0";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("MX737")){
			file = new File("/dev/ttyMT1");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyMT1";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("US821")){
			file = new File("/dev/ttyMT1");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyMT1";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("tb8788p1_64_bsp")){
			file = new File("/dev/ttyXRUSB0");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyXRUSB0";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("US835")){
			file = new File("/dev/ttyMT2");
			if (file.exists() == true) {
				this.sPort = "/dev/ttyMT2";
				this.iBaudRate = 115200;
			}
		}
		else if(Build.MODEL.equals("A108Plus")){
			file = new File("/dev/ttyMT2");
			if (file.exists() == true) {
				this.sPort = "/dev/ttyMT2";
				this.iBaudRate = 115200;
			}
		}
		else if(Build.MODEL.equals("US823")){
			file = new File("/dev/ttyHSL2");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyHSL2";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("US830")){
			file = new File("/dev/ttyHSL2");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyHSL2";
				this.iBaudRate=115200;
			}
		}
		else if(Build.MODEL.equals("US833")){
			file = new File("/dev/ttyHSL0");
			if(file.exists()==true) {
				this.sPort = "/dev/ttyHSL0";
				this.iBaudRate=115200;
			}
		}
        else if(Build.MODEL.equals("CJ-P1")){
            file = new File("/dev/ttyS9");
            if(file.exists()==true) {
                this.sPort = "/dev/ttyS9";
                this.iBaudRate=115200;
            }
        }
		else {
			file = new File("/dev/ttyHSL1");
			if (file.exists() == true) {
				this.sPort = "/dev/ttyHSL1";
				this.iBaudRate = 115200;
			}
		}
		file = new File("/dev/ttySAC1");
		if(file.exists()==true) {
			this.sPort = "/dev/ttySAC1";
			this.iBaudRate=115200;
		}
		//this.sPort = "/dev/ttyUSB2";
		//this("/dev/ttyACM0",115200);
	}
	public SerialHelper(String sPort){
		this(sPort,115200);
	}
	public SerialHelper(String sPort, String sBaudRate){
		this(sPort,Integer.parseInt(sBaudRate));
	}
	//----------------------------------------------------
	public void open() throws SecurityException, IOException,InvalidParameterException{

		mSerialPort =  new SerialPort(new File(sPort), iBaudRate, 0);

		mOutputStream = mSerialPort.getOutputStream();
		mInputStream = mSerialPort.getInputStream();
		mReadThread = new ReadThread();
		mReadThread.start();

		//mSendThread = new SendThread();
		//mSendThread.setSuspendFlag();
		//mSendThread.start();
		_isOpen=true;
	}
	public void createRecvThread()
	{
		mReadThread = new ReadThread();
		mReadThread.start();
	}
	//----------------------------------------------------
	public void close(){
		if (mReadThread != null)
			mReadThread.interrupt();
		if (mSerialPort != null) {
			mSerialPort.close();
			mSerialPort = null;
		}
		_isOpen=false;
	}
	public void Push(byte[] bInArray,int length){
		if(ofst_free+length<FifoBuffer.length) {
			System.arraycopy(bInArray, 0, FifoBuffer, ofst_free, length);
			ofst_free = ofst_free + length;
		}
		else {
			System.arraycopy(bInArray, 0, FifoBuffer, ofst_free, FifoBuffer.length-ofst_free);
			System.arraycopy(bInArray, FifoBuffer.length - ofst_free, FifoBuffer, 0, length + ofst_free - FifoBuffer.length);
			ofst_free = length+ofst_free-FifoBuffer.length;
		}
	}
	public int Pop(byte[] bOutArray,int timeout){
		for(int i=0;i<timeout;i+=100){
			if(ofst_free!=ofst_last){
				bOutArray[0]=FifoBuffer[ofst_last++];
				//Log.d("SerialHelper", "Pop: "+ByteUtil.bytearrayToHexString(bOutArray,1));
				ofst_last %= FifoBuffer.length;
				return 0;
			}
			try
			{
				Thread.sleep(100);
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
		return 1;
	}

//	public void onMcuPower(){
//		if (mSerialPort != null) {
//			mSerialPort.mcupowerA316(1);
//		}
//	}
//
//	public void offMcuPower(){
//		//Log.d(LOGTAG, "+ offMcuPower ");
//		if (mSerialPort != null) {
//			//Log.d("SerialHelper", "-offMcuPower");
//			mSerialPort.mcupowerA316(0);
//		}
//
//	}
	public void Quick32Crc(byte[] bData,int length,byte[] crcOut)
	{
		if (mSerialPort != null) {
			mSerialPort.QuickCrc32(bData, length, crcOut);
		}
	}
//	public void Crc16CCITT(byte[] bData,int length,byte[] crcOut)
//	{
//		if (mSerialPort != null) {
//			mSerialPort.Crc16CCITT(bData, length, crcOut);
//		}
//	}
	//----------------------------------------------------
	public void send(byte[] bOutArray){
		try{
//			Log.d("SerialHelper","send: " +ByteUtil.bytearrayToHexString(bOutArray,bOutArray.length));
			mOutputStream.write(bOutArray);
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	//----------------------------------------------------
//	public void sendHex(String sHex){
//		byte[] bOutArray = MyFunc.HexToByteArr(sHex);
//		send(bOutArray);
//	}
	//----------------------------------------------------
	public void sendTxt(String sTxt){
		byte[] bOutArray =sTxt.getBytes();
		send(bOutArray);		
	}
	//----------------------------------------------------
	private class ReadThread extends Thread {
		@Override
		public void run() {
			super.run();
			while(!isInterrupted()) {
				try
				{
					if (mInputStream == null) return;

					int len = mInputStream.available();

					if(len > 0)
					{
						byte[] buffer = new byte[len];

						int size = mInputStream.read(buffer);
						if (size > 0){
							Push(buffer, size);
							//send(buffer);
//							Log.d("SerialHelper", "recv:" + ByteUtil.bytearrayToHexString(buffer, size));
							//Log.d("SerialHelper")
						}
					}
				} catch (Throwable e)
				{
					e.printStackTrace();
					return;
				}
			}
		}
	}
	//----------------------------------------------------
	private class SendThread extends Thread{
		public boolean suspendFlag = true;// �����̵߳�ִ��
		@Override
		public void run() {
			super.run();
			while(!isInterrupted()) {
				synchronized (this)
				{
					while (suspendFlag)
					{
						try
						{
							wait();
						} catch (InterruptedException e)
						{
							e.printStackTrace();
						}
					}
				}
				send(getbLoopData());
				try
				{
					Thread.sleep(iDelay);
				} catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		}

		//�߳���ͣ
		public void setSuspendFlag() {
		this.suspendFlag = true;
		}
		
		//�����߳�
		public synchronized void setResume() {
		this.suspendFlag = false;
		notify();
		}
	}
	//----------------------------------------------------
	public int getBaudRate()
	{
		return iBaudRate;
	}
	public boolean setBaudRate(int iBaud)
	{
		if (_isOpen)
		{
			return false;
		} else
		{
			iBaudRate = iBaud;
			return true;
		}
	}
	public boolean setBaudRate(String sBaud)
	{
		int iBaud = Integer.parseInt(sBaud);
		return setBaudRate(iBaud);
	}
	//----------------------------------------------------
	public String getPort()
	{
		return sPort;
	}
	public boolean setPort(String sPort)
	{
		if (_isOpen)
		{
			return false;
		} else
		{
			this.sPort = sPort;
			return true;
		}
	}
	//----------------------------------------------------
	public boolean isOpen()
	{
		return _isOpen;
	}
	//----------------------------------------------------
	public byte[] getbLoopData()
	{
		return _bLoopData;
	}
	//----------------------------------------------------
	public void setbLoopData(byte[] bLoopData)
	{
		this._bLoopData = bLoopData;
	}
	//----------------------------------------------------
	public void setTxtLoopData(String sTxt){
		this._bLoopData = sTxt.getBytes();
	}
	//----------------------------------------------------
//	public void setHexLoopData(String sHex){
//		this._bLoopData = MyFunc.HexToByteArr(sHex);
//	}
	//----------------------------------------------------
	public int getiDelay()
	{
		return iDelay;
	}
	//----------------------------------------------------
	public void setiDelay(int iDelay)
	{
		this.iDelay = iDelay;
	}
	//----------------------------------------------------
	public void startSend()
	{
		if (mSendThread != null)
		{
			mSendThread.setResume();
		}
	}
	//----------------------------------------------------
	public void stopSend()
	{
		if (mSendThread != null)
		{
			mSendThread.setSuspendFlag();
		}
	}
	public void sendMcuCommand(String command){
		CharSequence t = command;
		int i;

		Log.d("SerialHelper", " " + t + " , length  " + t.length());
		char[] text = new char[t.length()];

		for (i = 0; i < t.length(); i++) {
			text[i] = t.charAt(i);
		}
		try {
			mOutputStream.write(new String(text).getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	//----------------------------------------------------
	//protected abstract void onDataReceived(ComBean ComRecData);
}